package com.cnhis.drgs.core.dao;
import com.cnhis.drgs.util.Util;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.*;
import com.cnhis.drgs.core.vo.Page;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

public class DbUtilsTemplate implements Dao {

    private DataSource dataSource;

    public DbUtilsTemplate() {

    }

    public DbUtilsTemplate(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public <T> Page queryPage(Page page, String sql, Class<T> clazz, Object... params) {
        String countSql = "SELECT COUNT(1) FROM (" + sql + ") t";
        int rowCount = getCount(countSql, params);
        page.setRowCount(rowCount);
        sql += " LIMIT " + page.getOffset() + "," + page.getPageSize();
        List<T> list = queryList(sql, clazz, params);
        page.setList(list);
        return page;
    }

    public <T> List<T> queryList(String sql, Class<T> clazz, Object... params) {
        try {
            QueryRunner queryRunner = new QueryRunner(dataSource);
            return queryRunner.query(sql, new BeanListHandler<>(clazz), params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Page queryPageMap(Page page, String sql, Object... params) {
        String countSql = "SELECT COUNT(1) FROM (" + sql + ") t";
        int rowCount = getCount(countSql, params);
        page.setRowCount(rowCount);
        sql += " LIMIT " + page.getOffset() + "," + page.getPageSize();
        List<Map<String, Object>> list = queryListMap(sql, params);
        page.setList(list);
        return page;
    }

    public List<Map<String, Object>> queryListMap(String sql, Object... params) {
        try {
            QueryRunner queryRunner = new QueryRunner(dataSource);
            return queryRunner.query(sql, new MapListHandler(), params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public <T> T queryFirst(String sql, Class<T> clazz, Object... params) {
        try {
            QueryRunner queryRunner = new QueryRunner(dataSource);
            return queryRunner.query(sql, new BeanHandler<>(clazz), params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Map<String, Object> queryFirstMap(String sql, Object... params) {
        try {
            QueryRunner queryRunner = new QueryRunner(dataSource);
            return queryRunner.query(sql, new MapHandler(), params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public int getCount(String sql, Object... params) {
        Map<String, Object> map = queryFirstMap(sql, params);
        if (map != null) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                return Integer.parseInt(entry.getValue().toString());
            }
        }
        return 0;

    }

    /**
     * 插入
     *
     * @param sql
     * @param params
     * @return 如果自增长，返回当前插入的自增长id值
     */
    public int insert(String sql, Object... params) {
        try {
            QueryRunner queryRunner = new QueryRunner(dataSource);
            Object[] objs = queryRunner.insert(sql, new ArrayHandler(), params);
            if (Util.isArrayNotEmpty(objs)) {
                Object obj = objs[0];
                try {
                    return Integer.parseInt(obj.toString());
                } catch (Exception ignored) {
                }
            }
            return 0;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    public int update(String sql, Object... params) {
        try {
            QueryRunner queryRunner = new QueryRunner(dataSource);
            return queryRunner.update(sql, params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }

    public int[] batch(String sql, Object[][] params) {
        try {
            QueryRunner queryRunner = new QueryRunner(dataSource);
            return queryRunner.batch(sql, params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

}
